/*
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Topless JSF.
 *
 * The Initial Developer of the Original Code is
 * Marco Antonio Villalobos, Jr. (mvillalobos@kineteque.com).
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Marco Antonio Villalobos, Jr. (mvillalobos@kineteque.com).
 *
 * ***** END LICENSE BLOCK *****
 */

package kineteque.jsf.topless.converters;

import kineteque.jsf.topless.util.JSONConverter;
import org.json.JSONException;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import java.util.List;

/**
 * Converts lists into JSON arrays, and JSON arrays into lists.
 */
@FacesConverter(value = "topless.jsonListConverter")
public class JSONListConverter implements Converter {
    /**
     * <p>Convert the specified string value, which is associated with
     * the specified {@link javax.faces.component.UIComponent}, into a model data object that
     * is appropriate for being stored during the <em>Apply Request
     * Values</em> phase of the request processing lifecycle.</p>
     *
     * @param context   {@link javax.faces.context.FacesContext} for the request being processed
     * @param component {@link javax.faces.component.UIComponent} with which this model object
     *                  value is associated
     * @param value     String value to be converted (may be <code>null</code>)
     * @return <code>null</code> if the value to convert is <code>null</code>,
     *         otherwise the result of the conversion
     * @throws javax.faces.convert.ConverterException
     *                              if conversion cannot be successfully
     *                              performed
     * @throws NullPointerException if <code>context</code> or
     *                              <code>component</code> is <code>null</code>
     */
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        try {
            return JSONConverter.jsonArrayToList(value);
        } catch (JSONException e) {
            throw new ConverterException(new StringBuilder().append("Failed to convert value = ").append(value).append(" into JSON Array").toString(), e);
        }
    }

    /**
     * <p>Convert the specified model object value, which is associated with
     * the specified {@link javax.faces.component.UIComponent}, into a String that is suitable
     * for being included in the response generated during the
     * <em>Render Response</em> phase of the request processing
     * lifeycle.</p>
     *
     * @param context   {@link javax.faces.context.FacesContext} for the request being processed
     * @param component {@link javax.faces.component.UIComponent} with which this model object
     *                  value is associated
     * @param value     Model object value to be converted
     *                  (may be <code>null</code>)
     * @return a zero-length String if value is <code>null</code>,
     *         otherwise the result of the conversion
     * @throws javax.faces.convert.ConverterException
     *                              if conversion cannot be successfully
     *                              performed
     * @throws NullPointerException if <code>context</code> or
     *                              <code>component</code> is <code>null</code>
     */
    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return JSONConverter.listToJsonArray((List)value);
    }
}
